/**
 * 
 */
package org.vsg.stock.basic.service.indicator.processor;

import java.text.DecimalFormat;
import java.util.List;
import java.util.Vector;

import org.apache.commons.math.linear.Array2DRowRealMatrix;
import org.apache.commons.math.linear.ArrayRealVector;
import org.apache.commons.math.linear.DecompositionSolver;
import org.apache.commons.math.linear.LUDecompositionImpl;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.linear.RealVector;
import org.vsg.stock.basic.service.indicator.shape.PoleLineEquation;
import org.vsg.stock.core.indicator.coordinate.CoefficientException;
import org.vsg.stock.core.indicator.coordinate.CoordinateContext;
import org.vsg.stock.core.indicator.coordinate.CoordinatePoint;
import org.vsg.stock.core.indicator.coordinate.OriginalDataPoint;
import org.vsg.stock.core.indicator.coordinate.Processor;
import org.vsg.stock.core.indicator.coordinate.ShapeEquation;
import org.vsg.stock.core.indicator.coordinate.UnitDefinition;
import org.vsg.stock.core.indicator.coordinate.origpoint.KLineLowOriginalDataPoint;
import org.vsg.stock.core.kline.DailyKLineStock;
import org.vsg.stock.core.utils.StockDateUtilExtension;

/**
 * @author Bill Vison
 *
 */
public class PoleLineProcessor implements Processor<DailyKLineStock>{

	private StockDateUtilExtension stkDateUtilExtension;
	
	private DecimalFormat df = new DecimalFormat("0.00");
	
	
	private OriginalDataPoint startPoint;
	
	private OriginalDataPoint endPoint;
	

	public OriginalDataPoint getStartPoint() {
		return startPoint;
	}


	public void setStartPoint(OriginalDataPoint startPoint) {
		this.startPoint = startPoint;
	}

	public OriginalDataPoint getEndPoint() {
		return endPoint;
	}

	public void setEndPoint(OriginalDataPoint endPoint) {
		this.endPoint = endPoint;
	}

	public void setStkDateUtilExtension(StockDateUtilExtension stkDateUtilExtension) {
		this.stkDateUtilExtension = stkDateUtilExtension;
	}



	@Override
	public List<ShapeEquation> process(CoordinateContext context,
			List<DailyKLineStock> dataList) {
		OriginalDataPoint originPoint = context.getOriginPoint();
		
		UnitDefinition udef = context.getUnitDefinition();
		
		List<CoordinatePoint> pointList =new Vector<CoordinatePoint>();
		
		
		CoordinatePoint startCoorPoint = context.transformToCoordinatePoint(this.startPoint);
		CoordinatePoint endCoorPoint = context.transformToCoordinatePoint(this.endPoint);
		
		//System.out.println(startCoorPoint + " ### " + endCoorPoint );
		
		// --- build 线性方程 ---
		double[][] coefficientsData = new double[2][2];
		coefficientsData[0] = new double[]{startCoorPoint.getXvalue(),1};
		coefficientsData[1] = new double[]{endCoorPoint.getXvalue(),1};

		RealMatrix coefficients =
		    new Array2DRowRealMatrix(
		    		coefficientsData,
		                       false);
		
		DecompositionSolver solver = new LUDecompositionImpl(coefficients).getSolver();
		
		RealVector constants = new ArrayRealVector(new double[] 
		                {startCoorPoint.getYvalue() ,endCoorPoint.getYvalue() }, false);
		RealVector solution = solver.solve(constants);
		
		
		// ---- 得出两个系数值 ----
		double a = solution.getEntry(0);
		double b = solution.getEntry(1);


		PoleLineEquation lineEquation = new PoleLineEquation();
		lineEquation.setCoefficientA( a );
		lineEquation.setCoefficientB( b );
		
		//System.out.println(a + " , " + b );

		
		// --- find all point ---
		for (DailyKLineStock kline : dataList) {
			
			// ---- get the x & y value ,最低价离原点收盘价 ---
			OriginalDataPoint dataPoint = new KLineLowOriginalDataPoint(kline);
			CoordinatePoint refPoint = context.transformToCoordinatePoint(dataPoint);
			
			//context.transformToOriginalDataPoint(refPoint);


			try {
				double y = lineEquation.testFormulaValue( refPoint.getXvalue() );
				double linePrice = Double.parseDouble( df.format( (originPoint.getYvalue() + y * udef.getYUnit() )  ) );
				//System.out.println("list : " +  kline.getDate() +" , " + linePrice);
			} catch (CoefficientException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			pointList.add( refPoint );
			
		}
		
		List<ShapeEquation> listVec = new Vector<ShapeEquation>();
		listVec.add( lineEquation );
		
		return listVec;
	}
	
	

	
	
}
